<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\Plugin\Radar\Action\Operation;

use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Utils\Codec\Json;
use MoChat\App\Corp\Contract\CorpContract;
use MoChat\App\Corp\Logic\AppTrait;
use MoChat\App\Utils\File;
use MoChat\App\WorkAgent\Contract\WorkAgentContract;
use MoChat\App\WorkAgent\QueueService\MessageRemind;
use MoChat\App\WorkContact\Contract\WorkContactContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Request\ValidateSceneTrait;
use MoChat\Plugin\AutoTag\Action\Dashboard\Traits\AutoContactTag;
use MoChat\Plugin\Radar\Contract\RadarChannelContract;
use MoChat\Plugin\Radar\Contract\RadarChannelLinkContract;
use MoChat\Plugin\Radar\Contract\RadarContract;
use MoChat\Plugin\Radar\Contract\RadarRecordContract;

/**
 * 互动雷达-H5 获取雷达信息.
 *
 * Class Show.
 * @Controller
 */
class GetRadar extends AbstractAction
{
    use ValidateSceneTrait;
    use AutoContactTag;
    use AppTrait;

    /**
     * @var RequestInterface
     */
    protected $request;

    /**
     * @Inject
     * @var RadarContract
     */
    protected $radarService;

    /**
     * @Inject
     * @var RadarRecordContract
     */
    protected $radarRecordService;

    /**
     * @Inject
     * @var WorkContactContract
     */
    protected $workContactService;

    /**
     * @Inject
     * @var RadarChannelContract
     */
    protected $radarChannelService;

    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Inject
     * @var RadarChannelLinkContract
     */
    protected $radarChannelLinkService;

    /**
     * @Inject
     * @var CorpContract
     */
    protected $corpService;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    /**
     * @Inject
     * @var MessageRemind
     */
    protected $messageRemind;

    /**
     * @Inject
     * @var WorkAgentContract
     */
    private $workAgentService;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    private $logger;

    /**
     * @RequestMapping(path="/operation/radar/getRadar", methods="get")
     * @return array 返回数组
     * @throws \JsonException
     */
    public function handle(): array
    {
        // 参数验证
        $this->validated($this->request->all());
        // 接收参数
        $params = [
            'union_id' => $this->request->input('union_id'),
            'nickname' => $this->request->input('nickname'),
            'avatar' => $this->request->input('avatar'),
            'type' => (int) $this->request->input('target_type'),
            'radar_id' => (int) $this->request->input('radar_id'),
            'link_id' => (int) $this->request->input('target_id'),
            'employeeId' => (int) $this->request->input('staff_id'),
        ];

        // 数据统计
        return $this->handleData($params);
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
            //            'union_id' => 'required',
            //            'nickname' => 'required',
            //            'avatar' => 'required',
            'target_type' => 'required',
            'radar_id' => 'required',
            'target_id' => 'required',
            'staff_id' => 'required',
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
            //            'union_id.required' => 'union_id 必传',
            //            'nickname.required' => 'nickname 必传',
            //            'avatar.required' => 'avatar 必传',
            'target_type.required' => 'target_type 必传',
            'radar_id.required' => 'radar_id 必传',
            'target_id.required' => 'target_id 必传',
            'staff_id.required' => 'staff_id 必传',
        ];
    }

    /**
     * @param $params
     * @throws \JsonException
     */
    private function handleData($params): array
    {
        // 雷达
        $radar = $this->radarService->getRadarById($params['radar_id'], ['type', 'title', 'link', 'pdf', 'article_type', 'article', 'action_notice', 'dynamic_notice', 'tag_status', 'contact_tags', 'employee_card', 'corp_id']);
        // 链接
        $link = $this->radarChannelLinkService->getRadarChannelLinkById($params['link_id'], ['id', 'channel_id', 'link', 'employee_id', 'click_num', 'click_person_num', 'qr_code']);
        // 渠道
        $channel = $this->radarChannelService->getRadarChannelById($link['channelId'], ['id', 'name', 'corp_id']);
        // 点击记录
        $info = $this->radarRecordService->getRadarRecordByUnionIdChannelIdRadarId($params['union_id'], $channel['id'], $params['radar_id'], ['contact_id']);
        $contactId = empty($info) ? 0 : $info[0]['contactId'];
        if ($contactId === 0) {
            $contact = $this->workContactService->getWorkContactByCorpIdUnionId($radar['corpId'], $params['union_id'], ['id']);

            $contactId = empty($contact) ? 0 : $contact['id'];
        }
        // 员工
        $employee = $this->workEmployeeService->getWorkEmployeeById($params['employeeId'], ['name', 'wx_user_id']);
        $content = "【雷达文章】\n「{$params['nickname']}」打开了「{$employee['name']}」在「自建渠道-{$channel['name']}」里发送的互动雷达「{$radar['title']}」\n客户昵称:{$params['nickname']}\n客户类型:微信客户\n<a href='{$link['link']}'>点击查看链接</a>";

        $data = [
            'radar_id' => $params['radar_id'],
            'channel_id' => $channel['id'],
            'type' => 1,
            'union_id' => $params['union_id'],
            'nickname' => $params['nickname'],
            'avatar' => $params['avatar'],
            'contact_id' => $contactId,
            'employee_id' => $params['employeeId'],
            'content' => $content,
            'corp_id' => $radar['corpId'],
            'created_at' => date('Y-m-d H:i:s'),
        ];
        // 添加点击记录
        $radar['clickId'] = $this->radarRecordService->createRadarRecord($data);
        if (empty($info)) {// 新客户
            $this->radarChannelLinkService->updateRadarChannelLinkById($params['link_id'], ['click_person_num' => $link['clickPersonNum'] + 1]);
            if ($contactId > 0 && $radar['tagStatus'] === 1 && ! empty($radar['contactTags'])) {
                $this->tag($params['employeeId'], $contactId, Json::decode($radar['contactTags']), $radar['corpId']);
            }
        }
        $this->radarChannelLinkService->updateRadarChannelLinkById($params['link_id'], ['click_num' => $link['clickNum'] + 1]);
        // 行为通知、雷达链接
        if ($radar['actionNotice'] === 1 && $radar['type'] === 1) {
            $this->logger->error('应用消息通知', $radar);
            $this->actionNotice($radar['corpId'], $employee['wxUserId'], $content);
        }
        // 返回数据处理
        if ($radar['type'] === 3) {
            $article = Json::decode($radar['article']);
            if ($radar['articleType'] === 2) {
                $article['pull_cover_url'] = file_full_url($article['cover_url']);
            }
            if ($radar['articleType'] === 1 && ! empty($article['content'])) {
                /* 图片处理 */
                $imgarr = [];
                $imgarr2 = [];
                // 匹配img标签
                preg_match_all("/<img([^>]*)\\s*src=('|\")([^'\"]+)('|\")/", $article['content'], $imgarr);
                // 去除重复
                $imgarr2 = array_unique($imgarr[3]);
                // 替换图片链接
                foreach ($imgarr2 as $k => $v) {
                    $article['content'] = str_replace($v, file_full_url($v), $article['content']);
                }
            }
            $radar['article'] = $article;
        }
        if ($radar['type'] === 3 && $radar['articleType'] === 2) {
            $radar['article']['cover_url'] = file_full_url($radar['article']['cover_url']);
        }
        $radar['employeeName'] = '';
        $radar['employeeAvatar'] = '';
        $radar['employeeMobile'] = '';
        $radar['qrCode'] = '';
        if ($radar['employeeCard'] === 1) {
            $employee = $this->workEmployeeService->getWorkEmployeeById($link['employeeId'], ['name', 'wx_user_id', 'avatar']);
            $radar['employeeName'] = $employee['name'] ?? '';
            $radar['employeeAvatar'] = empty($employee['avatar']) ? '' : file_full_url($employee['avatar']);
            $radar['employeeMobile'] = $employee['mobile'] ?? '';
            $radar['qrCode'] = $this->getQRcode($radar['corpId'], (int) $params['radar_id'], $employee['wxUserId'], $link);
        }
        return $radar;
    }

    private function getQRcode(int $corpId, int $radarId, string $wxUserId, array $link): string
    {
        if (! empty($link['qrCode'])) {
            return file_full_url($link['qrCode']);
        }
        # #EasyWeChat配置客户联系「联系我」方式
        $res = $this->wxApp($corpId, 'contact')->contact_way->create(1, 2, [
            'skip_verify' => true,
            'state' => 'radar-' . $radarId,
            'user' => [$wxUserId],
        ]);
        if ($res['errcode'] !== 0) {
            $this->logger->error(sprintf('生成二维码 失败::[%s]', Json::encode($res)));
            return '';
        }

        # # 二维码本地保存
        $pic = File::uploadUrlImage($res['qr_code'], 'image/fission/' . strval(microtime(true) * 10000) . '_' . uniqid() . '.jpg');
        $this->radarChannelLinkService->updateRadarChannelLinkById($link['id'], ['qr_code' => $pic['path']]);
        return $pic['fullPath'];
    }

    /**
     * @throws \JsonException
     */
    private function actionNotice(int $corpId, string $wxUserId, string $content): void
    {
        $this->messageRemind->sendToEmployee($corpId, $wxUserId, 'text', $content);
    }

    private function tag(int $employeeId, int $contactId, array $tags, int $corpId): void
    {
        $data = ['contactId' => 0, 'employeeId' => 0, 'tagArr' => array_column($tags, 'tagid'), 'employeeWxUserId' => '', 'contactWxExternalUserid' => ''];
        // 客户id
        $data['contactId'] = $contactId;
        $data['employeeId'] = $employeeId;
        // 客户
        $contact = $this->workContactService->getWorkContactById($contactId, ['wx_external_userid']);
        if (empty($contact)) {
            return;
        }
        $data['contactWxExternalUserid'] = $contact['wxExternalUserid'];
        // 员工
        $employee = $this->workEmployeeService->getWorkEmployeeById($employeeId, ['wx_user_id']);
        if (empty($employee)) {
            return;
        }
        $data['employeeWxUserId'] = $employee['wxUserId'];
        $data['corpId'] = $corpId;
        $this->autoTag($data);
    }
}
